Questionnaire on Well-Being (QWB), 18 items, each item is scored on a scale of 0 to 4 (Hlynsson et al. 2024). Data from the same paper. We’ll use the data from the first study that was used in the EFA in the paper.
Code
### import data - this is just sample code, the files do not exist
d1 <- read_excel("data/study_one.xlsx") # replace with your datafile as needed
### Load item information
# make sure that variable names in df match with itemlabels$itemnr
itemlabels <- data.frame(
stringsAsFactors = FALSE,
itemnr = paste0("swb", 1:18),
item = c(
"... felt calm and relaxed?",
"... had a good appetite and enjoyed eating?",
"... have been able to take initiatives and get started with what you wanted to do?",
"... felt optimistic and viewed things on the bright side?",
"... felt active and filled with energy?",
"... felt a strong zest for life?",
"... been able to object and to assert yourself when this is needed?",
"... felt satisfied with your life in its present situation?",
"... felt that your life is meaningful?",
"... slept well and got the right amount of sleep?",
"... have been able to be focused and concentrated on today’s tasks?",
"... felt interested in various activities and in people around you?",
"... felt happy and harmonious?",
"... felt satisfied with yourself?",
"... been able to make decisions and carry them out?",
"... been able to stay in the here and now and to let go of thoughts about problems?",
"... had the power to recover one’s strength if something has been stressful or difficult?",
"... felt that you are well and healthy?"
)
)
#write_csv(itemlabels,"data/itemlabels_swb.csv")All participants that have missing data are completely missing (no missing data on item level), except one respondent with 33.3% missing. We will remove all those with any missing responses from our data.
We end up with 494 respondents, which is identical to the complete responders in the paper.
1 All items in the analysis
Code
RIlistitems(df)| itemnr | item |
|---|---|
| swb1 | ... felt calm and relaxed? |
| swb2 | ... had a good appetite and enjoyed eating? |
| swb3 | ... have been able to take initiatives and get started with what you wanted to do? |
| swb4 | ... felt optimistic and viewed things on the bright side? |
| swb5 | ... felt active and filled with energy? |
| swb6 | ... felt a strong zest for life? |
| swb7 | ... been able to object and to assert yourself when this is needed? |
| swb8 | ... felt satisfied with your life in its present situation? |
| swb9 | ... felt that your life is meaningful? |
| swb10 | ... slept well and got the right amount of sleep? |
| swb11 | ... have been able to be focused and concentrated on today’s tasks? |
| swb12 | ... felt interested in various activities and in people around you? |
| swb13 | ... felt happy and harmonious? |
| swb14 | ... felt satisfied with yourself? |
| swb15 | ... been able to make decisions and carry them out? |
| swb16 | ... been able to stay in the here and now and to let go of thoughts about problems? |
| swb17 | ... had the power to recover one’s strength if something has been stressful or difficult? |
| swb18 | ... felt that you are well and healthy? |
2 Descriptives of raw data
Response distribution for all items are summarized below.
Code
RIallresp(df)| Response category | Number of responses | Percent |
|---|---|---|
| 0 | 537 | 6.0 |
| 1 | 2432 | 27.4 |
| 2 | 3422 | 38.5 |
| 3 | 1981 | 22.3 |
| 4 | 520 | 5.8 |
2.1 Descriptives - item level
Code
RIlistItemsMargin(df, fontsize = 12)| itemnr | item |
|---|---|
| swb1 | … felt calm and relaxed? |
| swb2 | … had a good appetite and enjoyed eating? |
| swb3 | … have been able to take initiatives and get started with what you wanted to do? |
| swb4 | … felt optimistic and viewed things on the bright side? |
| swb5 | … felt active and filled with energy? |
| swb6 | … felt a strong zest for life? |
| swb7 | … been able to object and to assert yourself when this is needed? |
| swb8 | … felt satisfied with your life in its present situation? |
| swb9 | … felt that your life is meaningful? |
| swb10 | … slept well and got the right amount of sleep? |
| swb11 | … have been able to be focused and concentrated on today’s tasks? |
| swb12 | … felt interested in various activities and in people around you? |
| swb13 | … felt happy and harmonious? |
| swb14 | … felt satisfied with yourself? |
| swb15 | … been able to make decisions and carry them out? |
| swb16 | … been able to stay in the here and now and to let go of thoughts about problems? |
| swb17 | … had the power to recover one’s strength if something has been stressful or difficult? |
| swb18 | … felt that you are well and healthy? |
Code
RItileplot(df)Code
RIbarstack(df)Code
RIbarplot(df)Code
Iteration in WLE/MLE estimation 1 | Maximal change 1.5065
Iteration in WLE/MLE estimation 2 | Maximal change 0.8894
Iteration in WLE/MLE estimation 3 | Maximal change 0.4824
Iteration in WLE/MLE estimation 4 | Maximal change 0.1072
Iteration in WLE/MLE estimation 5 | Maximal change 0.0011
Iteration in WLE/MLE estimation 6 | Maximal change 0.0001
----
WLE Reliability= 0.933
....................................................
Plots exported in png format into folder:
/Users/magnuspjo/Documents/Hub/rasch_välmåendeskalan/Plots
Some cells have few (4-6) responses. No items need reverse scoring.
3 Exploratory factor analysis
Let’s look at the data using EFA. A lot of the code for this analysis was borrowed from https://solomonkurz.netlify.app/blog/2021-05-11-yes-you-can-fit-an-exploratory-factor-analysis-with-lavaan/
Since the paper used varimax rotation and WLSMV estimator, we will do the same.
Code
library(lavaan)
f1 <- 'efa("efa")*f1 =~ swb1 + swb2 + swb3 + swb4 + swb5 + swb6 + swb7 + swb8 +
swb9 + swb10 + swb11 + swb12 + swb13 + swb14 + swb15 +
swb16 + swb17 + swb18'
# 2-factor model
f2 <- 'efa("efa")*f1 +
efa("efa")*f2 =~ swb1 + swb2 + swb3 + swb4 + swb5 + swb6 + swb7 + swb8 +
swb9 + swb10 + swb11 + swb12 + swb13 + swb14 + swb15 +
swb16 + swb17 + swb18'
# 3-factor
f3 <- '
efa("efa")*f1 +
efa("efa")*f2 +
efa("efa")*f3 =~ swb1 + swb2 + swb3 + swb4 + swb5 + swb6 + swb7 + swb8 +
swb9 + swb10 + swb11 + swb12 + swb13 + swb14 + swb15 +
swb16 + swb17 + swb18'
# 4-factor
f4 <- '
efa("efa")*f1 +
efa("efa")*f2 +
efa("efa")*f3 +
efa("efa")*f4 =~ swb1 + swb2 + swb3 + swb4 + swb5 + swb6 + swb7 + swb8 +
swb9 + swb10 + swb11 + swb12 + swb13 + swb14 + swb15 +
swb16 + swb17 + swb18'
# 5-factor
f5 <- '
efa("efa")*f1 +
efa("efa")*f2 +
efa("efa")*f3 +
efa("efa")*f4 +
efa("efa")*f5 =~ swb1 + swb2 + swb3 + swb4 + swb5 + swb6 + swb7 + swb8 +
swb9 + swb10 + swb11 + swb12 + swb13 + swb14 + swb15 +
swb16 + swb17 + swb18'
efa_f1 <-
cfa(model = f1,
data = df,
rotation = "varimax",
estimator = "WLSMV",
ordered = TRUE)
efa_f2 <-
cfa(model = f2,
data = df,
rotation = "varimax",
estimator = "WLSMV",
ordered = TRUE)
efa_f3 <-
cfa(model = f3,
data = df,
rotation = "varimax",
estimator = "WLSMV",
ordered = TRUE)
efa_f4 <-
cfa(model = f4,
data = df,
rotation = "varimax",
estimator = "WLSMV",
ordered = TRUE)
efa_f5 <-
cfa(model = f5,
data = df,
rotation = "varimax",
estimator = "WLSMV",
ordered = TRUE)3.1 Scaled fit metrics
For WLSMV, the .scaled metrics should be reported.
Code
fit_metrics_scaled <- c("chisq.scaled", "df", "pvalue.scaled",
"cfi.scaled", "tli.scaled", "rmsea.scaled",
"rmsea.ci.lower.scaled","rmsea.ci.upper.scaled",
"srmr")
rbind(
fitmeasures(efa_f1, fit_metrics_scaled),
fitmeasures(efa_f2, fit_metrics_scaled),
fitmeasures(efa_f3, fit_metrics_scaled),
fitmeasures(efa_f4, fit_metrics_scaled),
fitmeasures(efa_f5, fit_metrics_scaled)
) %>%
as.data.frame() %>%
mutate(across(where(is.numeric),~ round(.x, 3))) %>%
rename(Chi2.scaled = chisq.scaled,
p.scaled = pvalue.scaled,
CFI.scaled = cfi.scaled,
TLI.scaled = tli.scaled,
RMSEA.scaled = rmsea.scaled,
CI_low.scaled = rmsea.ci.lower.scaled,
CI_high.scaled = rmsea.ci.upper.scaled,
SRMR = srmr) %>%
add_column(Model = paste0(1:5,"-factor"), .before = "Chi2.scaled") %>%
knitr::kable()| Model | Chi2.scaled | df | p.scaled | CFI.scaled | TLI.scaled | RMSEA.scaled | CI_low.scaled | CI_high.scaled | SRMR |
|---|---|---|---|---|---|---|---|---|---|
| 1-factor | 894.634 | 135 | 0 | 0.944 | 0.937 | 0.107 | 0.100 | 0.114 | 0.061 |
| 2-factor | 642.016 | 118 | 0 | 0.961 | 0.950 | 0.095 | 0.088 | 0.102 | 0.050 |
| 3-factor | 390.419 | 102 | 0 | 0.979 | 0.968 | 0.076 | 0.068 | 0.084 | 0.035 |
| 4-factor | 255.405 | 87 | 0 | 0.988 | 0.978 | 0.063 | 0.054 | 0.072 | 0.028 |
| 5-factor | 172.833 | 73 | 0 | 0.993 | 0.985 | 0.053 | 0.043 | 0.063 | 0.021 |
Since these are ordinal data used with WLSMV, we cannot apply rule of thumb cutoff values such as Hu & Bentler (1999), since those are based on continuous data and maximum likelihood estimation. But we can see what happens with the different metrics in the different models and how they compare.
3.2 Factor loadings 1-factor
Code
standardizedsolution(efa_f1) %>%
filter(op == "=~") %>%
mutate(item = str_remove(rhs, "swb") %>% as.double(),
factor = str_remove(lhs, "f")) lhs op rhs est.std se z pvalue ci.lower ci.upper item factor
1 f1 =~ swb1 0.783 0.019 40.224 0 0.745 0.821 1 1
2 f1 =~ swb2 0.566 0.031 18.301 0 0.505 0.627 2 1
3 f1 =~ swb3 0.534 0.031 17.199 0 0.473 0.595 3 1
4 f1 =~ swb4 0.715 0.024 30.156 0 0.668 0.761 4 1
5 f1 =~ swb5 0.740 0.022 34.159 0 0.698 0.783 5 1
6 f1 =~ swb6 0.743 0.022 34.237 0 0.700 0.785 6 1
7 f1 =~ swb7 0.815 0.016 52.008 0 0.784 0.846 7 1
8 f1 =~ swb8 0.873 0.014 63.481 0 0.846 0.900 8 1
9 f1 =~ swb9 0.784 0.021 37.401 0 0.743 0.825 9 1
10 f1 =~ swb10 0.784 0.020 39.219 0 0.745 0.823 10 1
11 f1 =~ swb11 0.778 0.020 38.898 0 0.739 0.817 11 1
12 f1 =~ swb12 0.679 0.026 25.989 0 0.628 0.730 12 1
13 f1 =~ swb13 0.404 0.039 10.468 0 0.328 0.479 13 1
14 f1 =~ swb14 0.627 0.029 21.782 0 0.571 0.683 14 1
15 f1 =~ swb15 0.777 0.018 42.393 0 0.742 0.813 15 1
16 f1 =~ swb16 0.687 0.026 26.849 0 0.637 0.737 16 1
17 f1 =~ swb17 0.769 0.019 40.441 0 0.732 0.807 17 1
18 f1 =~ swb18 0.685 0.024 28.688 0 0.638 0.731 18 1
All loadings (est.std in the table above) are above 0.4 in the one-factor model. Let’s review the modification indices, filtered to only include those with mi/chi2 values above 15.
3.3 Modification indices 1-factor
Code
| lhs | op | rhs | mi | epc | sepc.lv | sepc.all | sepc.nox |
|---|---|---|---|---|---|---|---|
| swb4 | ~~ | swb5 | 64.432 | -0.210 | -0.210 | -0.448 | -0.448 |
| swb7 | ~~ | swb8 | 47.569 | -0.161 | -0.161 | -0.568 | -0.568 |
| swb1 | ~~ | swb2 | 34.092 | -0.190 | -0.190 | -0.371 | -0.371 |
| swb15 | ~~ | swb17 | 27.174 | -0.140 | -0.140 | -0.348 | -0.348 |
| swb5 | ~~ | swb12 | 22.817 | -0.138 | -0.138 | -0.281 | -0.281 |
| swb11 | ~~ | swb17 | 22.577 | -0.131 | -0.131 | -0.326 | -0.326 |
| swb1 | ~~ | swb16 | 20.692 | -0.142 | -0.142 | -0.313 | -0.313 |
| swb5 | ~~ | swb6 | 19.294 | -0.123 | -0.123 | -0.273 | -0.273 |
| swb1 | ~~ | swb14 | 17.851 | -0.155 | -0.155 | -0.320 | -0.320 |
| swb7 | ~~ | swb11 | 15.753 | -0.102 | -0.102 | -0.280 | -0.280 |
| swb10 | ~~ | swb15 | 15.145 | -0.109 | -0.109 | -0.279 | -0.279 |
Here we can see several large residual correlations. These are the top 8:
- items 4 and 5
- 7 and 8
- 1 and 2
- 15 and 17
- 5 and 12
- 11 and 17
- 1 and 16
- 5 and 6
There seems to be some clustering going on here, which indicates multiple dimensions.
Let’s look at the 3 factor model as a comparison, and review how the items listed above fit in the 3 factors.
3.4 Plot 3-factor model
In the paper, the lowest standardized factor loading considered acceptable is 0.3, so we will use that here as well.
Code
standardizedsolution(efa_f3) %>%
filter(op == "=~") %>%
mutate(item = str_remove(rhs, "swb") %>% as.double(),
factor = str_remove(lhs, "f")) %>%
# plot
ggplot(aes(x = est.std, xmin = ci.lower, xmax = ci.upper, y = item)) +
annotate(geom = "rect",
xmin = -1, xmax = 1,
ymin = -Inf, ymax = Inf,
fill = "grey90") +
annotate(geom = "rect",
xmin = -0.7, xmax = 0.7,
ymin = -Inf, ymax = Inf,
fill = "grey93") +
annotate(geom = "rect",
xmin = -0.3, xmax = 0.3,
ymin = -Inf, ymax = Inf,
fill = "grey96") +
geom_vline(xintercept = 0, color = "white") +
geom_pointrange(aes(alpha = abs(est.std) < 0.3),
fatten = 10) +
geom_text(aes(label = item, color = abs(est.std) < 0.3),
size = 4) +
scale_color_manual(values = c("white", "transparent")) +
scale_alpha_manual(values = c(1, 1/3)) +
scale_x_continuous(expression(lambda[standardized]),
expand = c(0, 0), limits = c(-1, 1),
breaks = c(-1, -0.7, -0.3, 0, 0.3, 0.7, 1),
labels = c("-1", "-.7", "-.3", "0", ".3", ".7", "1")) +
scale_y_continuous(breaks = 1:18, sec.axis = sec_axis(~ . * 1, breaks = 1:18)) +
ggtitle("Factor loadings for the 3-factor model") +
theme(legend.position = "none") +
facet_wrap(~ factor, labeller = label_both) Several crossloadings are apparent when using the low cutoff of 0.3. Let’s raise the bar to 0.4 and perhaps achieve more clarity.
Code
standardizedsolution(efa_f3) %>%
filter(op == "=~") %>%
mutate(item = str_remove(rhs, "swb") %>% as.double(),
factor = str_remove(lhs, "f")) %>%
# plot
ggplot(aes(x = est.std, xmin = ci.lower, xmax = ci.upper, y = item)) +
annotate(geom = "rect",
xmin = -1, xmax = 1,
ymin = -Inf, ymax = Inf,
fill = "grey90") +
annotate(geom = "rect",
xmin = -0.7, xmax = 0.7,
ymin = -Inf, ymax = Inf,
fill = "grey93") +
annotate(geom = "rect",
xmin = -0.4, xmax = 0.4,
ymin = -Inf, ymax = Inf,
fill = "grey96") +
geom_vline(xintercept = 0, color = "white") +
geom_pointrange(aes(alpha = abs(est.std) < 0.4),
fatten = 10) +
geom_text(aes(label = item, color = abs(est.std) < 0.4),
size = 4) +
scale_color_manual(values = c("white", "transparent")) +
scale_alpha_manual(values = c(1, 1/3)) +
scale_x_continuous(expression(lambda[standardized]),
expand = c(0, 0), limits = c(-1, 1),
breaks = c(-1, -0.7, -0.4, 0, 0.4, 0.7, 1),
labels = c("-1", "-.7", "-.4", "0", ".4", ".7", "1")) +
scale_y_continuous(breaks = 1:18, sec.axis = sec_axis(~ . * 1, breaks = 1:18)) +
ggtitle("Factor loadings for the 3-factor model") +
theme(legend.position = "none") +
facet_wrap(~ factor, labeller = label_both) These are the residual correlations from the 1-factor model sorted into factors in the model above:
factor 1:
- 4 and 5
- 5 and 6
- 5 and 12
factor 2:
- 1 and 2
- 1 and 16
factor 3:
- 7 and 8
- 15 and 17
- 11 and 17
Item pairs with residual correlations indicates that either the items make up a separate dimension/cluster in data, and/or they are too similar in content and only one of the two items can be included in the scale.
For unidimensionality to hold, there cannot be local dependence between items - items should only be related through the latent variable. Residuals are the variance in an item that is not explained by the latent variable, and thus the pattern of residuals is important to assess local dependence. Residual correlations are such a pattern.
3.5 Modification indices 3-factor
Code
| lhs | op | rhs | mi | epc | sepc.lv | sepc.all | sepc.nox |
|---|---|---|---|---|---|---|---|
| swb15 | ~~ | swb17 | 24.233 | -0.144 | -0.144 | -0.389 | -0.389 |
| swb7 | ~~ | swb8 | 16.739 | -0.148 | -0.148 | -0.729 | -0.729 |
| swb6 | ~~ | swb15 | 14.164 | 0.145 | 0.145 | 0.371 | 0.371 |
| swb7 | ~~ | swb15 | 12.128 | 0.118 | 0.118 | 0.380 | 0.380 |
| swb6 | ~~ | swb7 | 10.764 | -0.114 | -0.114 | -0.355 | -0.355 |
| swb10 | ~~ | swb15 | 10.318 | -0.095 | -0.095 | -0.258 | -0.258 |
| swb12 | ~~ | swb13 | 9.720 | -0.146 | -0.146 | -0.233 | -0.233 |
| swb8 | ~~ | swb17 | 7.809 | 0.104 | 0.104 | 0.430 | 0.430 |
| swb5 | ~~ | swb6 | 7.246 | -0.113 | -0.113 | -0.347 | -0.347 |
| swb9 | ~~ | swb14 | 7.198 | 0.114 | 0.114 | 0.250 | 0.250 |
| swb7 | ~~ | swb17 | 7.063 | 0.095 | 0.095 | 0.313 | 0.313 |
| swb5 | ~~ | swb18 | 6.130 | 0.117 | 0.117 | 0.327 | 0.327 |
| swb2 | ~~ | swb9 | 5.476 | -0.093 | -0.093 | -0.208 | -0.208 |
| swb16 | ~~ | swb18 | 5.095 | -0.088 | -0.088 | -0.191 | -0.191 |
A lot of residual correlations, particularly in the 3rd factor, which also has the most items.
4 Summary comments
These 18 items are clearly not unidimensional and should not be sum scored. Further work is needed to assess dimensionality to arrive at a set of items that fulfill unidimensionality requirements.
5 Software used
Code
R version 4.4.1 (2024-06-14)
Platform: aarch64-apple-darwin20
Running under: macOS Sonoma 14.6.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: Europe/Stockholm
tzcode source: internal
attached base packages:
[1] grid stats4 stats graphics grDevices utils datasets
[8] methods base
other attached packages:
[1] lavaan_0.6-18 TAM_4.2-21 CDM_8.2-6
[4] RISEkbmRasch_0.2.4.4 janitor_2.2.0 iarm_0.4.3
[7] hexbin_1.28.4 catR_3.17 glue_1.7.0
[10] ggrepel_0.9.6 patchwork_1.3.0 reshape_0.8.9
[13] matrixStats_1.4.1 psychotree_0.16-1 psychotools_0.7-4
[16] partykit_1.2-22 mvtnorm_1.3-1 libcoin_1.0-10
[19] psych_2.4.6.26 mirt_1.42 lattice_0.22-6
[22] eRm_1.0-6 kableExtra_1.4.0 formattable_0.2.1
[25] lubridate_1.9.3 forcats_1.0.0 stringr_1.5.1
[28] dplyr_1.1.4 purrr_1.0.2 readr_2.1.5
[31] tidyr_1.3.1 tibble_3.2.1 ggplot2_3.5.1
[34] tidyverse_2.0.0 readxl_1.4.3
loaded via a namespace (and not attached):
[1] vcd_1.4-12 rstudioapi_0.16.0 audio_0.1-11
[4] jsonlite_1.8.9 magrittr_2.0.3 farver_2.1.2
[7] rmarkdown_2.28 vctrs_0.6.5 base64enc_0.1-3
[10] htmltools_0.5.8.1 curl_5.2.3 cellranger_1.1.0
[13] Formula_1.2-5 dcurver_0.9.2 parallelly_1.38.0
[16] htmlwidgets_1.6.4 plyr_1.8.9 testthat_3.2.1.1
[19] zoo_1.8-12 admisc_0.35 lifecycle_1.0.4
[22] pkgconfig_2.0.3 Matrix_1.7-0 R6_2.5.1
[25] fastmap_1.2.0 snakecase_0.11.1 future_1.34.0
[28] numDeriv_2016.8-1.1 digest_0.6.37 colorspace_2.1-1
[31] rprojroot_2.0.4 Hmisc_5.1-3 vegan_2.6-8
[34] labeling_0.4.3 progressr_0.14.0 fansi_1.0.6
[37] timechange_0.3.0 abind_1.4-5 mgcv_1.9-1
[40] compiler_4.4.1 here_1.0.1 vcdExtra_0.8-5
[43] withr_3.0.1 htmlTable_2.4.3 backports_1.5.0
[46] carData_3.0-5 relimp_1.0-5 R.utils_2.12.3
[49] MASS_7.3-61 sessioninfo_1.2.2 GPArotation_2024.3-1
[52] permute_0.9-7 pbivnorm_0.6.0 tools_4.4.1
[55] foreign_0.8-87 lmtest_0.9-40 future.apply_1.11.2
[58] nnet_7.3-19 quadprog_1.5-8 R.oo_1.26.0
[61] nlme_3.1-165 inum_1.0-5 checkmate_2.3.2
[64] cluster_2.1.6 generics_0.1.3 snow_0.4-4
[67] gtable_0.3.5 RPushbullet_0.3.4 tzdb_0.4.0
[70] ca_0.71.1 R.methodsS3_1.8.2 data.table_1.16.0
[73] hms_1.1.3 car_3.1-2 xml2_1.3.6
[76] Deriv_4.1.3 utf8_1.2.4 pillar_1.9.0
[79] splines_4.4.1 survival_3.7-0 tidyselect_1.2.1
[82] pbapply_1.7-2 knitr_1.48 gridExtra_2.3
[85] svglite_2.1.3 xfun_0.46 gnm_1.1-5
[88] brio_1.1.5 stringi_1.8.4 yaml_2.3.10
[91] evaluate_0.24.0 codetools_0.2-20 beepr_2.0
[94] cli_3.6.3 rpart_4.1.23 qvcalc_1.0.3
[97] systemfonts_1.1.0 munsell_0.5.1 Rcpp_1.0.13
[100] globals_0.16.3 polycor_0.8-1 parallel_4.4.1
[103] listenv_0.9.1 viridisLite_0.4.2 SimDesign_2.17.1
[106] scales_1.3.0 rlang_1.1.4 mnormt_2.1.1